<?php

namespace app\common\command;

use app\common\model\card\Card;
use payment\{SlashService, WorldFirstService};
use think\console\Command;
use think\console\input\Argument;
use think\console\Input;
use think\console\Output;
use think\facade\Db;
use think\facade\Log;

class QueryCardList extends Command
{
    protected function configure()
    {
        $this->setName('query_card_list')
            ->addArgument('type', Argument::OPTIONAL, "worldfirst or import")
            ->setDescription('该功能用于同步万里付卡片，手动执行worldfirst后再执行import');
    }

    protected function execute(Input $input, Output $output)
    {
        $type = trim($input->getArgument('type'));
        if (!in_array($type, ['worldfirst', 'import'])) {
            $output->error('type 参数必须是 "worldfirst" 或 "import"');
            return;
        }

        // 创建锁文件
        $lockFile = runtime_path() . 'lock/query_card_list.lock';
        $lockDir = dirname($lockFile);

        // 确保锁目录存在
        if (!is_dir($lockDir)) {
            mkdir($lockDir, 0755, true);
        }

        // 尝试获取文件锁
        $fp = fopen($lockFile, 'w+');
        if (!$fp) {
            // 使用 trace() 函数记录错误，这个更可靠
            trace('无法创建锁文件: ' . $lockFile, 'error');
            return false;
        }

        // 尝试获取独占锁
        if (!flock($fp, LOCK_EX | LOCK_NB)) {
            Log::channel('card_query')->info('任务正在执行中，跳过本次执行');
            fclose($fp);
            return false;
        }

        try {
            // 写入进程ID和时间戳
            $lockInfo = [
                'pid' => getmypid(),
                'start_time' => date('Y-m-d H:i:s'),
                'memory_usage' => memory_get_usage(true),
                'type' => $type
            ];
            ftruncate($fp, 0);
            fwrite($fp, json_encode($lockInfo));
            fflush($fp);

            Log::channel('card_query')->info("开始执行卡片查询命令 - 类型: {$type}");

            $output->writeln("开始更新卡列表");

            if ($type == 'worldfirst') {
                $this->worldfirst();
            } elseif ($type == 'import') {
                $this->import();
            }

            $output->writeln("卡片查询命令执行完成");
            Log::channel('card_query')->info('卡片查询命令执行完成');

            // 更新锁文件信息，记录完成时间
            $lockInfo['end_time'] = date('Y-m-d H:i:s');
            $lockInfo['status'] = 'completed';
            ftruncate($fp, 0);
            fwrite($fp, json_encode($lockInfo));
            fflush($fp);

            return true;

        } catch (\Exception $e) {
            Log::channel('card_query')->error('卡片查询命令执行失败: ' . $e->getMessage());

            // 更新锁文件信息，记录错误状态
            $lockInfo['end_time'] = date('Y-m-d H:i:s');
            $lockInfo['status'] = 'error';
            $lockInfo['error'] = $e->getMessage();
            ftruncate($fp, 0);
            fwrite($fp, json_encode($lockInfo));
            fflush($fp);

            return false;

        } finally {
            // 释放锁并关闭文件
            flock($fp, LOCK_UN);
            fclose($fp);
        }
    }

    private function worldfirst()
    {
        try {
            Log::channel('worldfirst_query')->info('开始同步万里付卡片列表');

            // 使用默认配置（worldfirst）
            $worldFirst = new WorldFirstService('worldfirst');
            
            // 如果需要使用香港配置，可以这样：
            // $worldFirst = new WorldFirstService('worldfirst_hk');
            
            $hasMore = true;
            $totalCards = 0;
            $successCards = 0;
            $failedCards = 0;

            $params = [
                'page_number' => 1,
                'page_size' => 20,
            ];

            // 同步前先删除数据库中万里付的卡片
//            $deletedCount = Db::table('sc_worldfirst_card')->delete();
//            Log::channel('worldfirst_query')->info("清空万里付卡片表，删除记录数: {$deletedCount}");

            while ($hasMore) {
                try {
                    Log::channel('worldfirst_query')->info("开始获取第 {$params['page_number']} 页卡片列表");
                    Log::channel('worldfirst_query')->info(json_encode($params));

                    $worldFirstResult = $worldFirst->getCardList($params);
                    $resultStatus = $worldFirstResult['result']['resultStatus'] ?? '';

                    if ($resultStatus != 'S') {
                        Log::channel('worldfirst_query')->error('万里付获取卡片列表失败，准备重试');
                        Log::channel('worldfirst_query')->error(json_encode($worldFirstResult));
                        
                        sleep(10);
                        $worldFirstResult = $worldFirst->getCardList($params);
                        
                        if ($resultStatus != 'S') {
                            Log::channel('worldfirst_query')->error('万里付获取卡片列表第二次失败');
                            Log::channel('worldfirst_query')->error(json_encode($worldFirstResult));
                            break;
                        }
                    }

                    $cardList = $worldFirstResult['cardList'] ?? [];
                    $pageCardCount = count($cardList);
                    $totalCards += $pageCardCount;
                    
                    Log::channel('worldfirst_query')->info("第 {$params['page_number']} 页获取到 {$pageCardCount} 张卡片");

                    foreach ($cardList as $card) {
                        try {
                            // 提取 dailyLimit 相关字段
                            $card['dailyLimitPercent'] = $card['cardLimitDetail']['dailyLimit']['percent'] ?? 0;
                            $card['dailyLimitCurrency'] = $card['cardLimitDetail']['dailyLimit']['range']['currency'] ?? '';
                            $card['dailyLimitValue'] = $card['cardLimitDetail']['dailyLimit']['range']['value'] ?? 0;
                            $card['dailyUsedCurrency'] = $card['cardLimitDetail']['dailyLimit']['used']['currency'] ?? '';
                            $card['dailyUsedValue'] = $card['cardLimitDetail']['dailyLimit']['used']['value'] ?? 0;

                            // 提取 monthlyLimit 相关字段
                            $card['monthlyLimitPercent'] = $card['cardLimitDetail']['monthlyLimit']['percent'] ?? 0;
                            $card['monthlyLimitCurrency'] = $card['cardLimitDetail']['monthlyLimit']['range']['currency'] ?? '';
                            $card['monthlyLimitValue'] = $card['cardLimitDetail']['monthlyLimit']['range']['value'] ?? 0;
                            $card['monthlyUsedCurrency'] = $card['cardLimitDetail']['monthlyLimit']['used']['currency'] ?? '';
                            $card['monthlyUsedValue'] = $card['cardLimitDetail']['monthlyLimit']['used']['value'] ?? 0;

                            // 提取 perTransactionLimit 相关字段
                            $card['perTransactionLimitCurrency'] = $card['cardLimitDetail']['perTransactionLimit']['currency'] ?? '';
                            $card['perTransactionLimitValue'] = $card['cardLimitDetail']['perTransactionLimit']['value'] ?? 0;

                            // 提取 perCardLimit 相关字段（可选）
                            if (isset($card['perCardLimit'])) {
                                $card['perCardLimitPercent'] = $card['cardLimitDetail']['perCardLimit']['percent'] ?? 0;
                                $card['perCardLimitCurrency'] = $card['cardLimitDetail']['perCardLimit']['range']['currency'] ?? '';
                                $card['perCardLimitValue'] = $card['cardLimitDetail']['perCardLimit']['range']['value'] ?? 0;
                                $card['perCardUsedCurrency'] = $card['cardLimitDetail']['perCardLimit']['used']['currency'] ?? '';
                                $card['perCardUsedValue'] = $card['cardLimitDetail']['perCardLimit']['used']['value'] ?? 0;
                            }

                            unset($card['cardLimitDetail']);

                            // 插入数据库
                            Db::table('sc_worldfirst_card')->insert($card);
                            $successCards++;
                            
                            Log::channel('worldfirst_query')->info("成功插入万里付卡片: {$card['cardNickName']} (ID: {$card['assetId']})");

                        } catch (\Exception $e) {
                            $failedCards++;
                            Log::channel('worldfirst_query')->error("插入万里付卡片数据失败: " . $e->getMessage());
                            Log::channel('worldfirst_query')->error(json_encode($card));
                            continue; // 跳过当前记录，继续处理下一条
                        }
                    }

                    // 检查是否还有下一页
                    $hasMore = $worldFirstResult['currentPageNumber'] < $worldFirstResult['totalPageNumber'];
                    $params['page_number'] = $params['page_number'] + 1;
                    
                    Log::channel('worldfirst_query')->info("当前页: {$worldFirstResult['currentPageNumber']}, 总页数: {$worldFirstResult['totalPageNumber']}, 是否继续: " . ($hasMore ? '是' : '否'));

                } catch (\Exception $e) {
                    Log::channel('worldfirst_query')->error("获取或处理万里付卡片列表失败: " . $e->getMessage());
                    Log::channel('worldfirst_query')->error(json_encode($params));
                    break; // 停止分页处理
                }
            }

            Log::channel('worldfirst_query')->info("万里付卡片同步完成 - 总卡片数: {$totalCards}, 成功: {$successCards}, 失败: {$failedCards}");

        } catch (\Exception $e) {
            Log::channel('worldfirst_query')->error('万里付卡片同步异常: ' . $e->getMessage());
        }
    }

    private function import()
    {
        try {
            Log::channel('worldfirst_import')->info('开始导入万里付卡片到主表');

            $worldFirst = new WorldFirstService('worldfirst');
            $items = Db::table('sc_worldfirst_card')
                ->where('assetId', '>', '2025053019027200121216902444316')
                ->select()
                ->order('assetId')
                ->toArray();

            Log::channel('worldfirst_import')->info("查询到需要导入的万里付卡片数量: " . count($items));

            $totalItems = count($items);
            $successItems = 0;
            $failedItems = 0;
            $skippedItems = 0;

            foreach ($items as $item) {
                try {
                    Log::channel('worldfirst_import')->info("开始处理万里付卡片: {$item['cardNickName']} (ID: {$item['assetId']})");

                    $card = Card::where('card_id', $item['assetId'])->find();
                    if (!empty($card)) {
                        Log::channel('worldfirst_import')->info("卡片已存在，跳过: {$item['assetId']}");
                        $skippedItems++;
                        continue; // 卡存在则跳过
                    }

                    Log::channel('worldfirst_import')->info("获取万里付卡片敏感信息");
                    $worldFirstResult = $worldFirst->getCardSensitiveInfo($item['assetId']);
                    Log::channel('worldfirst_import')->info(json_encode($worldFirstResult));

                    if ($worldFirstResult['result']['resultStatus'] != 'S') {
                        Log::channel('worldfirst_import')->error('查看敏感信息失败: ' . $worldFirstResult['result']['resultMessage']);
                        $failedItems++;
                        continue;
                    }

                    $cardSecure = json_encode([
                        'card_num' => $worldFirstResult['cardNo'],
                        'cvv' => $worldFirstResult['cvv'],
                        'expiry_month' => $worldFirstResult['expiredMonth'],
                        'expiry_year' => $worldFirstResult['expiredYear'],
                    ]);

                    $secureMsg = encrypt($cardSecure);

                    $cardData = [
                        'card_id' => $item['assetId'],
                        'card_no' => $worldFirstResult['cardNo'],
                        'card_bin' => 10,
                        'user_pid' => 0,
                        'user_id' => 39,
                        'available_balance' => 0,
                        'alias' => $item['cardNickName'] ?? '',
                        'status' => $item['cardStatus'] == 'ACTIVE' ? 1 : 0,
                        'card_nick_name' => $item['cardNickName'],
                        'card_group_id' => '',
                        'group_id' => 63,
                        'tag_ids' => '',
                        'single_transaction_limit' => $item['perTransactionLimitValue'] / 100 ?? '0',
                        'daily_transaction_limit' => $item['dailyLimitValue'] / 100 ?? '0',
                        'monthly_transaction_limit' => $item['monthlyLimitValue'] / 100 ?? '0',
                        'total_transaction_limit' => $item['perCardLimitValue'] / 100 ?? '0',
                        'secure_msg' => $secureMsg,
                        'create_time' => time(),
                        'update_time' => time(),
                    ];

                    Card::create($cardData);
                    $successItems++;

                    Log::channel('worldfirst_import')->info("成功导入万里付卡片: {$item['cardNickName']} (ID: {$item['assetId']})");

                } catch (\Exception $e) {
                    $failedItems++;
                    Log::channel('worldfirst_import')->error("导入万里付卡片失败: " . $e->getMessage());
                    Log::channel('worldfirst_import')->error(json_encode($item));
                }
            }

            Log::channel('worldfirst_import')->info("万里付卡片导入完成 - 总数: {$totalItems}, 成功: {$successItems}, 失败: {$failedItems}, 跳过: {$skippedItems}");

        } catch (\Exception $e) {
            Log::channel('worldfirst_import')->error('万里付卡片导入异常: ' . $e->getMessage());
        }
    }

    /**
     * 根据业务需求使用不同的WorldFirst配置
     * @param string $businessType 业务类型：'main' 或 'hk'
     */
    private function worldfirstWithConfig($businessType = 'main')
    {
        try {
            Log::channel('worldfirst_query')->info("开始同步万里付卡片列表 - 业务类型: {$businessType}");

            // 根据业务类型选择配置
            $configName = $businessType === 'hk' ? 'worldfirst_hk' : 'worldfirst';
            $worldFirst = new WorldFirstService($configName);
            
            Log::channel('worldfirst_query')->info("使用配置: {$configName}");

            // 这里可以添加具体的业务逻辑
            // 例如：获取卡片列表、处理卡片信息等
            
            Log::channel('worldfirst_query')->info("万里付卡片同步完成 - 业务类型: {$businessType}");

        } catch (\Exception $e) {
            Log::channel('worldfirst_query')->error("万里付卡片同步异常 - 业务类型: {$businessType}: " . $e->getMessage());
        }
    }
}